const FILE_TYPPE_MAP = {
    'default': 'default',
    'jpg': 'image',
    'jpeg': 'image',
    'jpe': 'image',
    'gif': 'image',
    'ico': 'image',
    'png': 'image',
    'tif': 'image',
    'tiff': 'image',
    'bmp': 'image',
    'text': 'txt',
    'zip': 'zip',
    'rar': 'zip',
    '7z': 'zip',
    'mp4': 'video',
    'wmv': 'video',
    'wm': 'video',
    'movie': 'video',
    'mov': 'video',
    'mpa': 'video',
    'mpeg': 'video',
    'mpg': 'video',
    'mpv': 'video',
    'avi': 'video',
    'ts': 'video',
    'm2t': 'video',
    '3gp': 'video',
    'f4v': 'video',
    'mkv': 'video',
    'asf': 'video',
    'flv': 'video',
    'rm': 'video',
    'rmvb': 'video',
    'acp': 'audio',
    'aif': 'audio',
    'm3u': 'audio',
    'mid': 'audio',
    'mp1': 'audio',
    'mp2': 'audio',
    'mp3': 'audio',
    'mpga': 'audio',
    'ram': 'audio',
    'wav': 'audio',
    'wma': 'audio',
    'pdf': 'pdf',
    'ppt': 'ppt',
    'pptx': 'ppt',
    'doc': 'doc',
    'docx': 'doc',
    'xls': 'xls',
    'xlsx': 'xls',
    'js': 'code',
    'jsp': 'code'
}

//上传状态
const UPLOAD_STATE_READY = 0,          //任务已添加
    UPLOAD_STATE_READING = 1,            //文件读取中
    UPLOAD_STATE_PROCESSING = 2,         //任务上传中
    UPLOAD_STATE_COMPLETE = 3,           //任务上传完成
    UPLOAD_STATE_FAST = 4,               //任务秒传
    UPLOAD_STATE_COMPARING = 6,          // 文件合片中
    UPLOAD_STATE_TRANSCODING = 7,          // 文件转码中

    UPLOAD_STATE_SKIP = -1,              //任务已跳过
    UPLOAD_STATE_CANCEL = -2,            //任务已取消
    UPLOAD_STATE_ERROR = -3              //任务已失败

const FAST_STATE_FALSE = 0,            //文件不存在
    FAST_STATE_TRUE = 1,                 //文件存在
    FAST_STATE_ERROR = -1                //文件查询失败

//状态提示
const stateTips = {
    status_ready: '等待上传',
    status_reading: '读取中',
    status_processing: '上传中',
    status_complete: '已完成',
    status_fast: '秒传',
    status_skip: '格式错误',
    status_cancel: '已取消',
    status_error: '已失败',
    status_comparing: '合片中',
    status_transcoding: '转码中',
}

const UNITS_FILE_SIZE = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB']
const blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice
$(function () {
    var app = new Vue({
        el: '#app',
        data: function () {
            return {
                scrollOps: {
                    vuescroll: {
                        mode: 'native',
                        sizeStrategy: 'percent',
                        detectResize: true
                    },
                    scrollPanel: {},
                    rail: {},
                    bar: {
                        onlyShowBarOnScroll: false,
                        keepShow: true,
                        background: '#c1c1c1'
                    }
                },
                loading: true,
                token: '',
                fileList: [],
                fileCount: 0,
                searchKey: '',
                fileItemIndex: null,
                fileItemMoreIndex: null,
                fileRenameIndex: null,
                renameInput: '',
                isLock: false,
                upload: null,
                fastWorker: null,
                UPLOAD_TASK_GUID: 0,
                uploadPopDisplay: false,
                uploadStatue: 'uploading',
                xhrUpload: null,
                reduceCount: 0,
                uploadConfig: {
                    fileUrl: '/taskadmin/order/preCreate',
                    uploadUrl: upload_service,
                    rapidUploadUrl: '/taskadmin/order/rapidUpload',
                    cancelUploadUrl: '/taskadmin/order/cancel',
                    listUrl: '/attachmentadmin/content/getAttachmentsByOrderIds',
                    target: document.getElementById('upload_input'),
                    view: document.getElementById('upload_view'),
                    chunkSize: 4 * 1024 * 1024,
                    reTryNum: 2,
                    allows: '.jpg,.jpeg,.png,.bmp,.mp3,.wav,.mp4,.mts,.avi',
                    isLog: true
                },
                uploadTipsDisplay: false,
                uploadTipsText: '--',
                uploadList: [],        // 上传任务list
                uploadIndex: 0,        // 上传任务索引
                uploadReTryCount: 0,   // 重试次数
                uploadStateIcon: false,  // 上传状态
                uploadDone: false,       // 上传完成
                obj_editor: '',
                card_id: '',
                editor_upload_btn: '',
                timer: null,
                orderIdList: {}
            }
        },
        methods: {
            uploadInit() {
                let self = this
                self.browserDetect()
                window.onbeforeunload = function (e) {
                    if (self.hasFileUpload()) {
                        return '有文件正在上传，离开此页将会取消上传'
                    }
                }
            },
            // 浏览器检测                                                                                                                              、、去1
            browserDetect() {
                if (window.XMLHttpRequest && window.FormData && window.File) {
                    console.info('fileUpload - ok')
                } else {
                    this.$message({
                        type: 'warning',
                        message: '您的浏览器版本太低了!请使用chrome,firefox,360极速模式,IE10+',
                        showClose: true,
                        duration: 0
                    })
                }
            },
            uploadPopShow() {
                let self = this
                if (this.uploadDone) {
                    this.uploadStatue = 'done'
                } else {
                    this.uploadStatue = 'uploading'
                }
                this.uploadPopDisplay = true
            },
            uploadPopHide() {
                this.uploadPopDisplay = false
                this.uploadTipsDisplay = false
                this.$message.closeAll()
                if (this.uploadDone) {
                    this.uploadList = []
                }
            },

            /**
             * 处理上传图标显示
             */
            handleUploadIconStatus() {
                let self = this
                self.editor_upload_btn.find('.icon-circle-box-svg').attr('stroke', '#409eff')
                self.editor_upload_btn.find('.btn-submiting').each(function (key, val) {
                    $(val).css('display', 'inline-block');
                    $(val).find('.' + self.uploadStatue).show().siblings().hide()
                    if (self.uploadStatue === 'error') {
                        self.editor_upload_btn.find('.upload-icon-box').addClass('error-upload-icon-box')
                    } else {
                        self.editor_upload_btn.find('.upload-icon-box').removeClass('error-upload-icon-box')
                    }
                })
            },
            /**
             * 添加上传任务
             * @param event
             */
            addTask(event) {
                let self = this
                let input = event.target
                this.obj_editor = $(event.target).parent().parent().parent();
                this.card_id = this.obj_editor.data('card_id');
                this.editor_upload_btn = $('.clipcloud-editor-upload-btn')
                /* 上传按钮样式处理 */

                /* 等待状态处理 */
                let files = input.files
                this.uploadStateIcon = true
                this.uploadPopShow()
                this.uploadStatue = 'uploading'

                this.handleUploadIconStatus()
                if (files) {
                    for (let i = 0, len = files.length; i < len; i++) {
                        self.createTask(input, files[i])
                    }
                } else {
                    self.createTask(input)
                }
                input.value = ''
            },
            //创建上传任务
            createTask(input, file) {
                let self = this
                if (!input && !file) return
                let name, size, sizeFm
                if (file) {
                    name = file.name || file.fileName
                    size = file.size || file.fileSize || 0
                    sizeFm = this.formatSize(size)
                } else {
                    name = this.cutString(input.value, '\\').slice(1) || input.value
                    size = -1
                }
                let task = {
                    id: ++this.UPLOAD_TASK_GUID,
                    index: self.uploadList.length,
                    name: name,
                    size: size,
                    sizeFm: sizeFm,
                    input: input,
                    file: file,
                    percent: '0%',
                    speedFm: '--',
                    obj: this.obj_editor,
                    card_id: this.card_id
                }
                self.fileTypeCheck(task)
                self.uploadList.push(task)
                self.startSequenceTask()
            },
            startSequenceTask(index) {
                let self = this
                if (index || index === 0) {
                    self.uploadList[index].state = UPLOAD_STATE_READY
                }
                if (self.uploadList.length > 0) {
                    for (let i = 0; i < self.uploadList.length; i++) {
                        if (self.uploadList[i].state === UPLOAD_STATE_PROCESSING) {
                            self.uploadDone = false
                            return
                        }
                    }
                    for (let i = 0; i < self.uploadList.length; i++) {
                        if (self.uploadList[i].state === UPLOAD_STATE_READY) {
                            self.uploadDone = false
                            self.uploadStatue = 'uploading'
                            self.handleUploadIconStatus()
                            self.doUpload(self.uploadList[i])
                            return
                        }
                    }
                    for (let i = 0; i < self.uploadList.length; i++) {
                        if (self.uploadList[i].state === UPLOAD_STATE_ERROR || self.uploadList[i].state === UPLOAD_STATE_SKIP) {
                            self.uploadDone = true
                            self.uploadStatue = 'done'
                            self.handleUploadIconStatus()
                            self.$message({
                                message: '上传完成，但有文件失败，请打开上传窗口查看',
                                type: 'error',
                                showClose: true,
                                duration: 0
                            })
                            return
                        }
                    }
                    self.$message({
                        message: '上传完成',
                        type: 'success'
                    })
                    self.uploadDone = true
                    self.uploadStatue = 'done'
                    self.handleUploadIconStatus()
                    self.uploadStateIcon = true
                }
            },
            doUpload(task) {
                if (!task || task.state != UPLOAD_STATE_READY || task.skip) return
                task.state = UPLOAD_STATE_PROCESSING
                if (!task.file) return this.complete(task, UPLOAD_STATE_SKIP)
                this.createUploadTask(task)
            },
            createUploadTask(task) {
                let self = this, url = self.uploadConfig.fileUrl, xhr = new XMLHttpRequest()
                let sendNum = 0
                let sendTask = function (task) {
                    xhr.onreadystatechange = function () {
                        if (xhr.readyState != 4) return
                        if (xhr.status >= 200 && xhr.status < 400) {
                            sendNum = 0
                            let responseData = JSON.parse(xhr.response)
                            if (responseData.status == '0') {
                                task.order_id = responseData.data.order_id
                                task.mediatype = responseData.data.mediatype
                                // upload
                                if (!self.fastWorker) self.fastWorker = new Worker(fastWorkerPath);
                                let obj = {
                                    instruct: 'start',
                                    data: {
                                        url: self.uploadConfig.rapidUploadUrl,
                                        name: task.name,
                                        files: task.file,
                                        order_id: responseData.data.order_id,
                                        chunkSize: self.uploadConfig.chunkSize,
                                    }
                                }
                                self.fastWorker.onmessage = function (e) {
                                    // console.log(e)
                                    task.MD5 = e.data.data.MD5
                                    task.MD5Time = e.data.data.MD5Time
                                    task.queryState = e.data.queryState
                                    if (e.data.queryState == FAST_STATE_TRUE) { // 已存在，秒传
                                        self.log('文件状态查询：已存在，秒传')
                                        task.state = UPLOAD_STATE_FAST
                                        self.complete(task, UPLOAD_STATE_FAST, responseData)
                                    }
                                    if (e.data.queryState == FAST_STATE_FALSE) { // 不存在
                                        self.log('文件状态查询：不存在')
                                    }
                                    if (e.data.queryState == FAST_STATE_ERROR) { // 查询错误
                                        self.log('文件状态查询：查询错误')
                                    }
                                }
                                self.fastWorker.postMessage(obj)
                                self.uploadSlice(task)
                            } else {
                                self.complete(task, UPLOAD_STATE_ERROR)
                                self.tipsInfo(responseData.msg, 'error')
                                self.log(responseData.msg)
                            }
                        }
                    }

                    xhr.onerror = function () {
                        if (task.state === UPLOAD_STATE_CANCEL) return
                        if (sendNum >= self.uploadConfig.reTryNum) {
                            self.complete(task, UPLOAD_STATE_ERROR)
                            self.tipsInfo('创建任务请求失败，请检查网络!', 'error')
                            self.log('创建任务请求失败，请检查网络!')
                            return
                        }
                        setTimeout(function () {
                            sendNum++
                            sendTask(task)
                        }, 3000)
                    }

                    xhr.ontimeout = function () {
                        console.info(sendNum)
                        if (task.state === UPLOAD_STATE_CANCEL) return
                        if (sendNum >= self.uploadConfig.reTryNum) {
                            self.complete(task, UPLOAD_STATE_ERROR)
                            self.tipsInfo('创建任务请求失败，请检查网络!', 'error')
                            self.log('创建任务请求失败，请检查网络!')
                            return
                        }
                        setTimeout(function () {
                            sendNum++
                            sendTask(task)
                        }, 3000)
                    }
                    if (xhr.timeout) {
                        xhr.timeout = 60000
                    }
                    xhr.open('POST', url, true)
                    let fd = new FormData
                    fd.append('platform', 'Web')
                    fd.append('mod', 'Task')
                    fd.append('act', 'PreCreate')
                    fd.append('title', task.name)
                    fd.append('filesize', task.size)
                    xhr.send(fd)
                }
                sendTask(task)
                return self
            },
            uploadSlice(task) {
                let self = this,
                    file = task.blob || task.file,
                    reader = new FileReader(),
                    size = task.size,
                    chunkSize = self.uploadConfig.chunkSize,
                    chunk,
                    chunkMd5 = '',
                    start = 0,
                    end = 0,
                    sliceIndex = 1,
                    completed = false
                task.sliceCount = Math.ceil(size / chunkSize)
                self.uploadReTryCount = 0
                self.xhrUpload = new XMLHttpRequest()
                let upload = function () {
                    let url = self.uploadConfig.uploadUrl + '?order_id=' + task.order_id + '&sliceCount=' + task.sliceCount + '&block=' + sliceIndex + '&blockmd5=' + chunkMd5
                    self.xhrUpload.upload.onprogress = function (e) {
                        self.progress(task, size, start + e.loaded)
                    }
                    self.xhrUpload.onreadystatechange = function (e) {
                        // console.log(self.xhrUpload.readyState)
                        if (self.xhrUpload.readyState !== 4) return
                        if (self.xhrUpload.status >= 200 && self.xhrUpload.status < 300) {
                            let responseData = JSON.parse(e.target.responseText)
                            if (responseData.status == '0') {
                                if (responseData.status == '0' && completed) {
                                    self.complete(task, UPLOAD_STATE_COMPLETE, responseData)
                                } else {
                                    nextUpload()
                                }
                            } else {
                                if (self.uploadReTryCount >= self.uploadConfig.reTryNum) {
                                    self.complete(task, UPLOAD_STATE_ERROR)
                                    self.tipsInfo('网络请求失败!', 'error')
                                    self.log('网络请求失败!')
                                    return
                                }
                                setTimeout(function () {
                                    self.uploadReTryCount++
                                    upload()
                                }, 3000)
                            }
                        }
                    }
                    self.xhrUpload.onerror = function () {
                        if (task.state === UPLOAD_STATE_CANCEL) return
                        if (self.uploadReTryCount >= self.uploadConfig.reTryNum) {
                            self.complete(task, UPLOAD_STATE_ERROR)
                            self.tipsInfo('网络请求失败!', 'error')
                            self.log('网络请求失败!')
                            return
                        }
                        setTimeout(function () {
                            self.uploadReTryCount++
                            upload()
                        }, 3000)
                    }

                    if (self.xhrUpload.timeout) self.xhrUpload.timeout = 60000
                    self.xhrUpload.open('POST', url)
                    let fd = new FormData
                    fd.append('file', chunk)
                    self.xhrUpload.send(fd)
                }

                //递归上传直至上传完毕
                let startUpload = function () {
                    if (start >= size || task.state !== UPLOAD_STATE_PROCESSING) return
                    end = start + chunkSize
                    if (end > size) end = size
                    if (end === size) completed = true
                    sliceIndex = Math.ceil(end / chunkSize)
                    chunk = blobSlice.call(file, start, end)
                    //获取当前分片md5
                    reader.onload = function (e) {
                        chunkMd5 = SparkMD5.ArrayBuffer.hash(e.target.result)
                        self.log(task.name + ': 上传分片 ' + sliceIndex + ' / ' + task.sliceCount + ' / ' + chunkMd5)
                        upload()
                    }
                    reader.readAsArrayBuffer(chunk)
                }
                //上传下一个分片
                let nextUpload = function () {
                    start = end
                    startUpload()
                }
                startUpload()
                self.afterSend(task)
            },
            afterSend(task) {
                let self = this
                task.lastTime = task.startTime = Date.now()
                self.progress(task)
            },

            progress(task, total, loaded) {
                let self = this
                if (!loaded || loaded < 0) loaded = 0
                let state = task.state || UPLOAD_STATE_READY
                if (loaded > total) loaded = total
                if (loaded > 0 && state === UPLOAD_STATE_READY) task.state = state = UPLOAD_STATE_PROCESSING
                let completed = state === UPLOAD_STATE_COMPLETE || state === UPLOAD_STATE_FAST
                if (completed) total = loaded = task.size
                //计算上传速度
                self.setTaskSpeed(task, total, loaded)
                task.total = total
                task.loaded = loaded
                task.loadedFm = self.formatSize(loaded)
                task.percent = Math.min(loaded * 100 / total || 0, 100).toFixed(1) + '%'
            },
            setTaskSpeed: function (task, total, loaded) {
                let self = this
                if (!total || total <= 0) return
                let nowTime = Date.now(), tick
                //平均速度
                if (loaded >= total) {
                    tick = nowTime - task.startTime
                    if (tick && typeof tick === 'number') {
                        task.avgSpeed = Math.min(Math.round(total * 1000 / tick), total)
                        task.avgSpeedFm = self.formatSize(task.avgSpeed)
                    } else {
                        task.avgSpeed = task.speed = 0
                        task.avgSpeedFm = self.formatSize(0)
                    }
                    task.time = tick || 0
                    task.endTime = nowTime
                }
                //即时速度
                tick = nowTime - task.lastTime
                if (tick < 200) return
                self.reduceCount++
                if (self.reduceCount % 5 === 0) {
                    self.reduceCount = 0
                    task.speed = Math.min(Math.round((loaded - task.loaded) * 1000 / tick), task.total)
                    task.speedFm = self.formatSize(task.speed)
                }
                task.lastTime = nowTime

            },
            complete(task, state, responseData) {
                let self = this
                if (!task) return self
                if (self.xhrUpload && (self.xhrUpload.readyState === 1 || self.xhrUpload.readyState === 2 || self.xhrUpload.readyState === 3)) {
                    self.xhrUpload.abort()
                }
                self.fastWorker && self.fastWorker.postMessage({
                    instruct: 'abort'
                })
                if (task.state !== UPLOAD_STATE_FAST) {
                    task.state = state
                    if (state === UPLOAD_STATE_CANCEL || state === UPLOAD_STATE_ERROR || !task.queryState) {
                        if (state === UPLOAD_STATE_ERROR) {
                            self.$message({
                                message: `【${task.name}】上传失败`,
                                type: 'error',
                                showClose: true,
                                duration: 5000
                            })
                        }
                    }
                }
                if (state === UPLOAD_STATE_COMPLETE || state === UPLOAD_STATE_FAST) {
                    task.percent = '100%'
                    self.setTaskAvgSpeed(task)
                    if (!self.orderIdList[task.order_id]) {
                        self.orderIdList[task.order_id] = {
                            obj: task.obj,
                            card_id: task.card_id
                        }
                    }
                    self.getFileList(task, self.timer)
                }
                task.responseData = responseData ? responseData : ''
                self.log(task.name + ': responseData ==> ' + JSON.stringify(task.responseData) || '')
                self.log(task.name + ': ' + self.$options.filters.uploadStatusTips(task.state) + '！')
                if (self.uploadList.length > 0) {
                    self.startSequenceTask()
                }
            },
            /**
             * 重新上传
             * @param index
             */
            reUpload(index) {
                let self = this
                this.uploadStatue = 'uploading'
                self.handleUploadIconStatus()
                if (self.hasFileUpload()) {
                    self.uploadList[index].state = UPLOAD_STATE_READY
                } else {
                    self.uploadList[index].state = UPLOAD_STATE_PROCESSING
                    self.createUploadTask(self.uploadList[index])
                }
            },
            /**
             * 取消上传
             * @param index
             */
            cancel(index) {
                let self = this
                if (self.uploadList[index].state === UPLOAD_STATE_PROCESSING) {
                    self.complete(self.uploadList[index], UPLOAD_STATE_CANCEL)
                } else {
                    self.uploadList[index].state = UPLOAD_STATE_CANCEL
                }
            },
            hasFileUpload() {
                for (let i = 0; i < this.uploadList.length; i++) {
                    if (this.uploadList[i].state === UPLOAD_STATE_READY || this.uploadList[i].state === UPLOAD_STATE_PROCESSING) {
                        return true
                    }
                }
                return false
            },
            setTaskAvgSpeed(task) {
                let loaded = task.loaded
                let nowTime = Date.now(), tick
                tick = nowTime - task.startTime
                task.avgSpeed = Math.min(Math.round(loaded * 1000 / tick), loaded)
                task.avgSpeedFm = this.formatSize(task.avgSpeed)
                task.speedFm = task.avgSpeedFm
            },
            log(msg) {
                // console.log(msg)
            },
            /**
             * 文件鼠标事件处理
             */
            listContainerMouseHandle(index, event) {
                if (this.isLock) return
                this.fileItemIndex = index
                if (event.type === 'mouseleave') {
                    this.fileItemMoreIndex = null
                }
            },
            /**
             * 文件操作Toggle
             */
            fileItemMoreToggle(index) {
                this.fileItemMoreIndex = this.fileItemMoreIndex || this.fileItemMoreIndex === 0 ? null : index
            },
            /**
             * 重命名
             */
            fileRename() {
                let self = this
                let params = {
                    mod: 'Attachment',
                    platform: 'Web',
                    act: 'FileRename',
                    attachment_id: self.fileList[self.fileRenameIndex]._id,
                    title: self.$refs.renameEl[0].value.trim(),
                    token: self.token
                }
                self.request('', params, (res) => {
                    self.$message({
                        type: 'success',
                        message: '操作成功，文件已重命名'
                    })
                    let title = self.$refs.renameEl[0].value.trim()
                    let suffix = title.substring(title.lastIndexOf('.') + 1)
                    self.fileList[self.fileRenameIndex].title = title
                    self.fileList[self.fileRenameIndex].suffix = suffix
                    self.fileRenameIndex = null
                    self.isLock = false
                }, (error) => {
                    self.$message({
                        type: 'waring',
                        message: `重命名失败，请重试(${error.status})`
                    })
                })
            },
            fileRenameBoxShow(type, index) {
                let self = this
                self.isLock = true
                self.fileItemMoreIndex = null
                self.fileRenameIndex = index
                self.$nextTick(() => {
                    let fileTitle = self.fileList[self.fileRenameIndex].title
                    let num = fileTitle.lastIndexOf('.')
                    self.$refs.renameEl[0].value = fileTitle
                    self.$refs.renameEl[0].focus()
                    self.$refs.renameEl[0].setSelectionRange(0, num)
                })

            },
            fileRenameBoxCancel() {
                let self = this
                self.isLock = false
                self.fileItemMoreIndex = null
                self.fileRenameIndex = null
            },
            /**
             * 文件删除
             * @param type
             * @param index
             */
            fileDelConfirm(type, index) {
                let self = this
                self.isLock = true
                self.fileItemMoreIndex = null
                self.$confirm(`确定删除 ${self.fileList[index].title} 文件吗?`, '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    self.fileDel(index)
                }).catch(() => {
                    self.isLock = false
                })
            },
            fileDel(index) {
                let self = this
                let params = {
                    mod: 'Attachment',
                    platform: 'Web',
                    act: 'Trash',
                    folders: '',
                    attachments: self.fileList[index]._id,
                    token: self.token
                }
                self.request('', params, (res) => {
                    self.$message({
                        type: 'success',
                        message: '操作成功，已删除'
                    })
                    self.getFileList()
                }, (error) => {
                    self.$message({
                        type: 'success',
                        message: `删除失败，请重试(${error.status})`
                    })
                })
                self.isLock = false
            },
            /**
             * 获取文件列表
             */
            getFileList(task, timer) {
                let order_id_list = Object.keys(this.orderIdList)
                let self = this
                let params = {
                    order_id: order_id_list.join(',')
                }
                if(!params.order_id) return
                self.request(self.uploadConfig.listUrl, params, (res) => {
                    if (res.data && res.data.attachments) {
                        let isEnd = false;
                        let objList = res.data.attachments
                        for (let i in objList) {
                            // 处理数据显示
                            let attachmentId = objList[i]._id
                            let trObj = $('tr[attachment_id=' + attachmentId + ']');
                            if (trObj.length === 0) {
                                showFile(objList[i], self.orderIdList[objList[i].order_id].obj, self.orderIdList[objList[i].order_id].card_id, trObj)
                            } else {
                                if (self.orderIdList[objList[i].order_id]) {
                                    replaceShowFile(objList[i], trObj, self.orderIdList[objList[i].order_id].obj, self.orderIdList[objList[i].order_id].card_id)
                                }
                            }
                            let dom = $('tr[attachment_id=' + attachmentId + ']');
                            if (objList[i].status == 1) {
                                dom.find('td:last').children('a,button').removeClass('disabled').show();
                                dom.find('td:last').find('.btn-state').remove()
                            }
                            if (objList[i].status == 6) {
                                dom.find('td:last').children('a,button').hide();
                                if (dom.find('td:last > span.btn-state').length > 0) {
                                    dom.find('td:last > span.btn-state').text('合片中');
                                } else {
                                    dom.find('td:last').append('<span class="btn-state">合片中</span>');
                                }
                            }
                            if (objList[i].status == 7) {
                                dom.find('td:last').children('a,button').hide();
                                if (dom.find('td:last > span.btn-state').length > 0) {
                                    dom.find('td:last > span.btn-state').text('转码中');
                                } else {
                                    dom.find('td:last').append('<span class="btn-state">转码中</span>');
                                }
                            }
                            if (!objList[i].filepath || objList[i].status != 1) {
                                isEnd = true;
                            } else {
                                delete (self.orderIdList[objList[i].order_id])
                            }
                        }
                        if (!isEnd) {
                            clearInterval(timer)
                            $('button[data_submit_type=submit_save_back]').removeClass('disabled')
                            $('button[data_submit_type=submit_cancel]').removeClass('disabled')
                        } else {
                            if (!timer) {
                                $('button[data_submit_type=submit_save_back]').addClass('disabled')
                                $('button[data_submit_type=submit_cancel]').addClass('disabled')
                                timer = setTimeout(() => {
                                    self.getFileList(task)
                                }, 1000)
                            }
                        }
                        // showFile(self.fileList, task.obj, task.card_id)
                    }
                }, (error) => {
                    self.$message({
                        type: 'error',
                        message: `操作失败，请重试！(${error.status})`
                    })
                })
            },
            clearSearchKey() {
                this.searchKey = ''
                this.getFileList()
            },
            /**
             * Ajax
             */
            request(url, params, success, error) {
                let self = this
                self.loading = true
                let xhr = new XMLHttpRequest()
                xhr.onreadystatechange = function () {
                    if (xhr.readyState != 4) return
                    if (xhr.status >= 200 && xhr.status < 400) {
                        let responseData = xhr.response ? JSON.parse(xhr.response) : {}
                        if (responseData.status == '0') {
                            console.log(responseData)
                            success && success(responseData)
                        } else {
                            error && error(responseData)

                        }
                    }
                    self.loading = false
                }
                xhr.onerror = function (e) {
                    self.loading = false
                    self.$message({
                        type: 'error',
                        message: '网络错误，请重试'
                    })
                }
                xhr.open('POST', url)
                let fd = new FormData
                for (let key in params) {
                    fd.append(key, params[key])
                }
                xhr.send(fd)
            },
            // 文件类型检查
            fileTypeCheck(task) {
                let self = this
                task.ext = self.cutString(task.name, '.').toLowerCase()
                // 判断文件格式是否允许上传
                if (self.uploadConfig.allows) {
                    let allowsMap = self.splitToMap(self.uploadConfig.allows)
                    let isSkip = !allowsMap[task.ext]
                    task.state = isSkip ? UPLOAD_STATE_SKIP : UPLOAD_STATE_READY
                    if (isSkip) {
                        task.disabled = true
                    }
                    if (task.disabled) {
                        let type = ''
                        for (let key in allowsMap) {
                            type += key + ', '
                        }
                        self.tipsInfo('允许上传的文件格式为：' + type, 'skip')
                        return false
                    }
                }

                task.state = UPLOAD_STATE_READY
                return true
            },
            parseLevel(size, steps, limit) {
                size = +size
                steps = steps || 1024
                let level = 0,
                    isNum = typeof steps == 'number',
                    stepNow = 1,
                    count = this.isUInt(limit) ? limit : (isNum ? 100 : steps.length)
                while (size >= stepNow && level < count) {
                    stepNow *= (isNum ? steps : steps[level])
                    level++
                }
                if (level && size < stepNow) {
                    stepNow /= (isNum ? steps : steps.last())
                    level--
                }
                return {value: level ? size / stepNow : size, level: level}
            },
            formatSize(size, ops) {
                ops = ops === true ? {all: true} : ops || {}
                if (isNaN(size) || size == undefined || size < 0) {
                    let error = ops.error || '--'
                    return ops.all ? {text: error} : error
                }
                let pl = this.parseLevel(size, ops.steps, ops.limit),
                    value = pl.value,
                    text = value.toFixed(this.defaultValue(ops.digit, 2))
                if (ops.trim !== false && text.lastIndexOf('.') != -1) text = text.replace(/\.?0+$/, '')
                pl.text = text + (ops.join || '') + (ops.units || UNITS_FILE_SIZE)[pl.level + (ops.start || 0)]
                return ops.all ? pl : pl.text
            },
            //检测是否为正整数
            isUInt(n) {
                return typeof n == 'number' && n > 0 && n === Math.floor(n)
            },
            defaultValue(value, defValue) {
                return value !== undefined ? value : defValue
            },
            //截取字符串
            cutString(str, find) {
                let index = str.lastIndexOf(find)
                return index != -1 ? str.slice(index) : ''
            },
            //逗号分隔转map
            splitToMap(str) {
                if (!str) return null
                let list = str.split(','), map = {}
                for (let i = 0; i < list.length; i++) {
                    map[list[i]] = true
                }
                return map
            },
            uploadStatusDisplay(state) {
                let className = ''
                switch (state) {
                    case UPLOAD_STATE_READY:
                        className = 'ready'
                        break
                    case UPLOAD_STATE_PROCESSING:
                        className = 'progress'
                        break
                    case UPLOAD_STATE_FAST:
                        className = 'fast'
                        break
                    case UPLOAD_STATE_COMPLETE:
                        className = 'complete'
                        break
                    case UPLOAD_STATE_ERROR:
                        className = 'error'
                        break
                    case UPLOAD_STATE_CANCEL:
                        className = 'cancel'
                        break
                    case UPLOAD_STATE_SKIP:
                        className = 'skip'
                        break
                    default:
                        className = ''
                }
                return className
            },
            uploadOperateDisplay(state) {
                return this.$options.filters.uploadStatusTips(state)
            },
            tipsInfo(msg, type) {
                let self = this
                switch (type) {
                    case 'error':
                        this.uploadStatue = 'error'
                        break
                    case 'info':
                        this.uploadStatue = 'uploading'
                        break
                    case 'skip':
                        this.uploadStatue = 'skip'
                        break
                    default:
                        this.uploadStatue = ''
                }
                self.handleUploadIconStatus()
                self.uploadTipsText = msg
                self.uploadTipsDisplay = true
            },
            destroy() {
                this.uploadList = []
                if (this.xhrUpload) {
                    this.xhrUpload.abort()
                    this.xhrUpload = null
                }
                this.$message.closeAll()
            },
            uploadStatusTips(state) {
                let tips = stateTips
                switch (state) {
                    case UPLOAD_STATE_READY:
                        return tips.status_ready
                    case UPLOAD_STATE_READING:
                        return tips.status_reading
                    case UPLOAD_STATE_PROCESSING:
                        return tips.status_processing
                    case UPLOAD_STATE_COMPLETE:
                        return tips.status_complete
                    case UPLOAD_STATE_FAST:
                        return tips.status_fast

                    case UPLOAD_STATE_SKIP:
                        return tips.status_skip
                    case UPLOAD_STATE_CANCEL:
                        return tips.status_cancel
                    case UPLOAD_STATE_ERROR:
                        return tips.status_error
                }
                return state
            }
        },
        created() {
        },
        mounted() {
            this.uploadInit()
            let self = this
            // 监听 input 上传
            $('#app').on('change', '.btn-fileupload', function (event) {

                self.addTask(event)
            })
            // this.token = getCookie('accessToken')
            // this.getFileList()
            /**
             * 切换模板编辑位置
             */
            $('body').on('click', '.nav-map', function () {
                /* 模板导航的样式处理 */
                $('.nav-map').removeClass('active');
                $(this).addClass('active');

                /* 切换编辑区域 */
                $('.edit-map').hide();
                var nav_id = $(this).attr('id');
                var edit_id = nav_id.replace('nav', 'edit');
                $('#' + edit_id).show();

                if ($('#' + edit_id).attr('id') == 'edit_related') {
                    $('#' + edit_id).css({'display': 'table'});
                }
            });

            $('body').on('click', '.btn-submiting', function () {
                self.uploadPopShow()
            })

            /**
             * 处理编辑快捷导航显示/隐藏事件
             */
            $('.btn-nav-archive').click(function () {
                var i = $(this).attr('btn_nav_archive_index');
                var obj_switch_btn = $('.btn-nav-archive').eq(i);
                if (obj_switch_btn.hasClass("active")) {
                    obj_switch_btn.removeClass("active");
                } else {
                    obj_switch_btn.addClass("active");
                }
            });

            /**
             * datepicker
             */
            $(".datepicker-input").each(function () {
                $(this).datepicker({language: "zh-CN", autoclose: true});
            });

            /**
             * datetimepicker
             */
            $(".datetimepicker-input").each(function () {
                $(this).datetimepicker({language: "zh-CN", autoclose: true});
            });

            /**
             * 初始化地区选单
             */
            $("select.region").each(function (k) {
                var pid = $(this).attr('data-init');
                if (k == 0) {
                    pid = pid ? pid : 3743;
                }
                if (pid > 0) {
                    getRegionByPid(pid, $(this));
                }
            });

            /**
             * 初始化案件类型、承办部门、案件标签
             */
            if ($.fn.select2) {
                /* 获取初始化内容 */
                var category_names = $('#category_names').val();
                var department_names = $('#department_names').val();
                var labels = $('#labels_title').val();

                /* 初始化案件类型 */
//        if (category_names) {
//            $("#category_name").select2({
//                tags: eval(category_names),
//                tokenSeparators: [",", " "]
//            });
//        }

                /* 初始化承办部门 */
//        if (department_names) {
//            $("#department_name").select2({
//                tags: eval(department_names),
//                tokenSeparators: [",", " "]
//            });
//        }

                /* 初始化案件标签 */
                if (labels) {
                    $(".archive-label").select2({
                        tags: eval(labels),
                        tokenSeparators: [",", " "]
                    });
                }
            }

            /**
             * 新增一个行动
             */
            $('#action_add_card').on('click', function () {
                add_card();
            });

            /**
             * 删除行动 - 显示/隐藏删除图标
             */
            $('#subNav').on('mouseover', 'li.nav-map', function () {
                if ($(this).find('.fa-ban').is(':hidden') == true && $(this).index() != 1) {
                    $(this).find('.fa-times').show();
                }
            });
            $('#subNav').on('mouseout', 'li.nav-map', function () {
                if ($(this).find('.fa-ban').is(':hidden') == true && $(this).index() != 1) {
                    $(this).find('.fa-times').hide();
                }
            });

            /**
             * 删除行动 - 执行删除
             * @todo 这个功能放到下期优化时加入
             */
//    $('#subNav').on('click', '.fa-times', function(){
//        var str_confirm = '确定要删除该行动吗？';
//        if (! confirm(str_confirm)) {
//            return false;
//        }
//
//        /* 删除行动菜单 */
//        var $li = $(this).parent().parent();
//        $li.addClass('disabled');
//        $(this).hide();
//        $li.find('.fa-ban').show();
//
//        /* 对应行动内容禁止编辑 */
//
//
//        /* 编辑状态下，记录删除的行动 ID */
//    });

            /**
             * 删除行动 - 执行删除
             * 1、已入库的行动，选择二次确认人；
             * 2、新增的行动，弹层二次确认后直接删除；
             */
            $('#subNav').on('click', '.fa-times', function () {
                var $li = $(this).parent().parent();

                if (!$li.attr('card_id')) {
                    var str_confirm = '确定要删除该新增的行动吗？';
                    if (!confirm(str_confirm)) {
                        return false;
                    }

                    /* 删除行动内容 */
                    var nav_id = $li.attr('id');
                    var edit_id = nav_id.replace('nav', 'edit');
                    $('#' + edit_id).remove();
                    $li.remove();
                } else {
                    del_nav_id = $li.attr('id');
                    $('#modal_select_confirm').modal('show');
                }
                return false;
            });

            /**
             * 选择删除二次确认人 - 处理选中状态
             */
            $('#modal_select_confirm').on('click', '.item-user', function () {
                if (!$(this).hasClass('active')) {
                    $('.item-user').removeClass('active');
                    $(this).addClass('active');
                } else {
                    $(this).removeClass('active');
                }
            });

            /**
             * 选择删除二次确认人 - 提交
             */
            $('#modal_select_confirm').on('click', '#submit_select_user', function () {
                /* 必须选择一个二次确认人 */
                var userid = null;
                $('.item-user').each(function () {
                    if ($(this).hasClass('active')) {
                        userid = $(this).data('userid');
                    }
                });
                if (!userid) {
                    alert('请选择一个二次确认人！');
                    return false;
                }

                /* 删除确认 */
                var str_confirm = '确定要申请删除该行动吗？';
                if (!confirm(str_confirm)) {
                    return false;
                }

                /* 记录删除的行动 ID */
                var del_card_ids = $('#delete_card_id').val();
                var del_card_ids_arr = del_card_ids ? del_card_ids.split(',') : new Array();
                del_card_ids_arr.push($('#' + del_nav_id).attr('card_id') + ':' + userid);
                $('#delete_card_id').val(del_card_ids_arr.join(','));

                /* 处理标签及对应内容的显示 */
                if ($('#' + del_nav_id).hasClass('active')) {
                    $('li#nav_base').addClass('active');
                    $('#edit_base').show();
                }

                /* 从页面上删除行动内容 */
                var edit_id = del_nav_id.replace('nav', 'edit');
                $('#' + edit_id).remove();
                $('#' + del_nav_id).remove();

                /* 提示 */
                alert('该行动的删除申请已记录，在您提交保存后，系统将自动发出该申请。')

                /* modal 层处理 */
                $('#modal_select_confirm').modal('hide');
            });

            /**
             * 删除行动 - 撤销删除
             * @todo 这个功能放到下期优化时加入
             */

            /**
             * 提交按钮处理
             */
            $(".input-submit").click(function () {
                var submit_type = $(this).attr("data_submit_type");
                switch (submit_type) {
                    case 'submit_cancel' :
                        form_cancel();
                        break;
                    case 'submit_save_back' :
                        back_listing = true;
                        form_submit();
                        break;
                    case 'submit_save_continue' :
                        back_listing = false;
                        form_submit();
                        break;
                }
            });


            /**
             * 删除资料 - 执行删除
             * 1、已入库的资料，选择二次确认人；
             * 2、新增的资料，弹层二次确认后直接删除；
             */
            $('#box_card').on('click', '.delete-single', function () {
                var $tr = $(this).parent().parent().parent();

                if (!$tr.attr('card_id')) {
                    var str_confirm = '确定要删除该新上传的资料吗？';
                    if (!confirm(str_confirm)) {
                        return false;
                    }

                    /* 删除资料 */
                    delAttachment($(this));
                } else {
                    del_a_id = $tr.attr('attachment_id');
                    $('#modal_select_confirm_a').modal('show');
                }
                return false;
            });

            /**
             * 选择删除二次确认人 - 处理选中状态
             */
            $('#modal_select_confirm_a').on('click', '.item-user', function () {
                if (!$(this).hasClass('active')) {
                    $('.item-user').removeClass('active');
                    $(this).addClass('active');
                } else {
                    $(this).removeClass('active');
                }
            });

            /**
             * 选择删除二次确认人 - 提交
             */
            $('#modal_select_confirm_a').on('click', '#submit_select_user_a', function () {
                /* 必须选择一个二次确认人 */
                var userid = null;
                $('.item-user').each(function () {
                    if ($(this).hasClass('active')) {
                        userid = $(this).data('userid');
                    }
                });
                if (!userid) {
                    alert('请选择一个二次确认人！');
                    return false;
                }

                /* 删除确认 */
                var str_confirm = '确定要申请删除该资料吗？';
                if (!confirm(str_confirm)) {
                    return false;
                }

                /* 记录删除的资料 ID */
                var del_a_ids = $('#delete_a_id').val();
                var del_a_ids_arr = del_a_ids ? del_a_ids.split(',') : new Array();
                del_a_ids_arr.push(del_a_id + ':' + userid);
                $('#delete_a_id').val(del_a_ids_arr.join(','));

                /* 从页面上删除该资料 */
                delAttachment($('#tr_a_' + del_a_id).find('.delete-single:last'));

                /* 提示 */
                alert('该资料的删除申请已记录，在您提交保存后，系统将自动发出该申请。')

                /* modal 层处理 */
                $('#modal_select_confirm_a').modal('hide');
            });
        },
        filters: {
            bytesToSize(bytes) {
                if (!bytes || bytes === 0) {
                    return '-'
                }
                const k = 1024
                const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
                let i = Math.floor(Math.log(bytes) / Math.log(k))
                return (bytes / Math.pow(k, i)).toPrecision(4) + ' ' + sizes[i]
            },
            /**
             * 文件扩展名处理
             * @param suffix
             * @returns {string|*}
             */
            suffixClass(suffix) {
                if (!suffix) {
                    return 'default'
                }
                if (suffix.indexOf('.') > -1) {
                    suffix = suffix.substring(1)
                }
                if (Object.keys(FILE_TYPPE_MAP).indexOf(suffix) > -1) {
                    return FILE_TYPPE_MAP[suffix]
                } else {
                    return 'default'
                }
            },
            fomatDate(timestamp) {
                const dt = new Date(timestamp)
                let y = dt.getFullYear()
                let m = (dt.getMonth() + 1).toString().padStart(2, '0')
                let d = dt.getDate().toString().padStart(2, '0')
                let hh = dt.getHours().toString().padStart(2, '0')
                let mm = dt.getMinutes().toString().padStart(2, '0')
                return `${y}-${m}-${d} ${hh}:${mm}`
            },
            uploadStatusTips(state) {
                let tips = stateTips
                switch (state) {
                    case UPLOAD_STATE_READY:
                        return tips.status_ready
                    case UPLOAD_STATE_READING:
                        return tips.status_reading
                    case UPLOAD_STATE_PROCESSING:
                        return tips.status_processing
                    case UPLOAD_STATE_COMPLETE:
                        return tips.status_complete
                    case UPLOAD_STATE_FAST:
                        return tips.status_fast

                    case UPLOAD_STATE_SKIP:
                        return tips.status_skip
                    case UPLOAD_STATE_CANCEL:
                        return tips.status_cancel
                    case UPLOAD_STATE_ERROR:
                        return tips.status_error
                }
                return state
            }
        },
        beforeRouteLeave(to, from, next) {
            if (this.hasFileUpload()) {
                this.$confirm('文件正在上传中, 确定离开?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    this.destroy()
                    next()
                }).catch(() => {
                    next(false)
                })
            } else {
                this.destroy()
                next()
            }
        }
    })
});